package co.gov.medellin.ssti.sub.paoyer.administration.dao;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import java.sql.PreparedStatement;

import co.gov.medellin.ssti.sub.paoyer.administration.model.vo.ProgramParameterVO;

/**
 * DAO para crear, consultar y actualizar registros en la tabla TCS_PARAM_REPTE.
 * 
 * @author Rene.Rangel@consultsoft.com
 * @version 1.0
 */

public class ProgramParameterDAO {
	/**
	 * Conexion a la base de datos.
	 */
	private Connection conn = null;

	/**
	 * Constructor que inicializa la conexion con la base de datos.
	 * 
	 * @param conn
	 *            Conexion con la base de datos.
	 */

	public ProgramParameterDAO(Connection conn) {
		this.conn = conn;
	}

	/**
	 * Consulta un grupo de registros de la tabla TCS_PARAM_REPTE a partir de
	 * las condiciones que vienen en el Value Object
	 * 
	 * @param ProgramParameterVO
	 *            Value Object con las condiciones a tener encuenta.
	 * 
	 * @return Collection Arreglo de registros retornados de la consulta.
	 */
	public Collection<ProgramParameterVO> findProgramParameterByCriterea(
			ProgramParameterVO criterea) throws SQLException {

		/**
		 * Aqui la busqueda se hace en la tabla Tcs_Param_Repte
		 */

		String query = "SELECT pare.*, prog.nombre programa, cofi.nombre consulta "
				+ "FROM tcs_param_repte pare, tcs_programa prog, tcs_consulta_fija cofi ";

		String filters = "";
		// Filtro por Nombre
		if ((criterea.getName() != null) && !(criterea.getName().equals(""))) {
			filters = filters + "AND UPPER(pare.nombre) LIKE '%"
					+ criterea.getName().toUpperCase() + "%' ";
		}

		// Filtro por Descripcion
		if ((criterea.getDescription() != null)
				&& !(criterea.getDescription().equals(""))) {
			filters = filters + " AND UPPER(pare.descripcion) LIKE '%"
					+ criterea.getDescription().toUpperCase() + "%' ";
		}

		// Filtro por Desde Vigencia
		if (criterea.getEffectiveFrom() != null) {
			filters = filters + " AND pare.desde_vigencia ="
					+ criterea.getEffectiveFrom();
		}

		// Filtro por Hasta Vigencia
		if (criterea.getEffectiveUntil() != null) {
			filters = filters + " AND pare.hasta_vigencia ="
					+ criterea.getEffectiveUntil();
		}

		// Filtro por Vigencia
		if (criterea.getUse() != null && !(criterea.getUse().equals(""))) {
			filters = filters + " AND pare.vigencia =" + criterea.getUse();
		}

		// Filtro por Tipo de Parametro
		if ((criterea.getParameterType() != null)
				&& !(criterea.getParameterType().equals(""))) {
			filters = filters + " AND pare.tipo ="
					+ criterea.getParameterType();
		}

		// Filtro por Obligatorio
		if ((criterea.getMandatory() != null)
				&& !(criterea.getMandatory().equals(""))) {
			filters = filters + " AND pare.oblig =" + criterea.getMandatory();
		}

		// Filtro por Etiqueta
		if ((criterea.getLabel() != null) && !(criterea.getLabel().equals(""))) {
			filters = filters + " AND pare.etiqueta =" + criterea.getLabel();
		}

		// Filtro por Tipo Dato
		if ((criterea.getDataType() != null)
				&& !(criterea.getDataType().equals(""))) {
			filters = filters + " AND pare.tipo_dato ="
					+ criterea.getDataType();
		}

		// Filtro por Valor por Defecto
		if ((criterea.getDefaultValue() != null)
				&& !(criterea.getDefaultValue().equals(""))) {
			filters = filters + " AND pare.val_defecto ="
					+ criterea.getDefaultValue();
		}

		// Filtro por Valor Alterno
		if ((criterea.getAlternativeValue() != null)
				&& !(criterea.getAlternativeValue().equals(""))) {
			filters = filters + " AND pare.val_alterno ="
					+ criterea.getAlternativeValue();
		}

		// Filtro por Orden
		if (criterea.getOrder() != null) {
			filters = filters + " AND pare.orden =" + criterea.getOrder();
		}

		// Filtro por Codigo de Programa
		if (criterea.getProgramCode() != null) {
			filters = filters + " AND pare.prg_codigo ="
					+ criterea.getProgramCode();
		}

		// Filtro por Codigo de Consulta Fija
		if (criterea.getFixedQueryCode() != null) {
			filters = filters + " AND pare.cfj_codigo ="
					+ criterea.getFixedQueryCode();
		}

		query = query
				+ " where cofi.codigo(+) = pare.cfj_codigo and prog.codigo = pare.prg_codigo ";

		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + filters;
		}

		Statement stm = null;
		ResultSet rst = null;
		ArrayList<ProgramParameterVO> programParameters = new ArrayList<ProgramParameterVO>();

		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			ProgramParameterVO programParameter = new ProgramParameterVO();
			programParameter.setCode(new Long(rst.getLong("codigo")));
			programParameter.setName(rst.getString("nombre"));
			programParameter.setDescription(rst.getString("descripcion"));
			programParameter.setWebUserCrea(rst.getString("usuario_crea"));
			programParameter.setWebClientCrea(rst.getString("terminal_crea"));
			programParameter.setWebUserModif(rst.getString("usuario_modifica"));
			programParameter.setWebClientModif(rst
					.getString("terminal_modifica"));
			programParameter.setEffectiveFrom(rst.getDate("desde_vigencia"));
			programParameter.setEffectiveUntil(rst.getDate("hasta_vigencia"));
			programParameter.setUse(rst.getString("vigencia"));
			programParameter.setParameterType(rst.getString("tipo"));
			programParameter.setMandatory(rst.getString("oblig"));
			programParameter.setLabel(rst.getString("etiqueta"));
			programParameter.setDataType(rst.getString("tipo_dato"));
			programParameter.setDefaultValue(rst.getString("val_defecto"));
			programParameter.setAlternativeValue(rst.getString("val_alterno"));
			programParameter.setOrder(new Short(rst.getShort("orden")));
			programParameter
					.setProgramCode(new Long(rst.getLong("prg_codigo")));
			programParameter.setParentProgramName(rst.getString("programa"));
			programParameter.setFixedQueryCode(new Long(rst
					.getLong("cfj_codigo")));
			programParameter.setParentFixedQueryName(rst.getString("consulta"));
			programParameters.add(programParameter);
		}

		stm.close();

		return programParameters;
	}

	/**
	 * Crea un nuevo registro en la tabla TCS_PARAM_REPTE.
	 * 
	 * @param ProgramParameterVO
	 *            Value Object con el registro que se va a Crear.
	 * 
	 * @return ProgramParameterVO Registro creado.
	 * 
	 */
	public ProgramParameterVO createProgramParameter(
			ProgramParameterVO newProgramParameter) throws SQLException {

		String strSQL = "";
		boolean result = false;
		PreparedStatement ps = null;
		strSQL = ""
				+ "INSERT INTO tcs_param_repte (codigo, nombre, descripcion, "
				+ "usuario_crea, terminal_crea, usuario_modifica, terminal_modifica, "
				+ "desde_vigencia, hasta_vigencia, vigencia, tipo, oblig, etiqueta, "
				+ "tipo_dato, val_defecto, val_alterno, orden, prg_codigo, cfj_codigo) "
				+ "VALUES(scs_param_repte.nextval,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";

		ps = conn.prepareStatement(strSQL);
		ps.setString(1, newProgramParameter.getName().toUpperCase());
		ps.setString(2, newProgramParameter.getDescription().toUpperCase());
		ps.setString(3, newProgramParameter.getWebUserCrea());
		ps.setString(4, "WEB=" + newProgramParameter.getWebClientCrea());
		ps.setString(5, newProgramParameter.getWebUserModif());
		ps.setString(6, "WEB=" + newProgramParameter.getWebClientModif());
		ps.setDate(7, newProgramParameter.getEffectiveFrom());
		ps.setDate(8, newProgramParameter.getEffectiveUntil());
		ps.setString(9, newProgramParameter.getUse().toUpperCase());
		ps.setString(10, newProgramParameter.getParameterType().toUpperCase());
		ps.setString(11, newProgramParameter.getMandatory().toUpperCase());
		ps.setString(12, newProgramParameter.getLabel().toUpperCase());
		ps.setString(13, newProgramParameter.getDataType().toUpperCase());
		ps.setString(14, newProgramParameter.getDefaultValue().toUpperCase());
		ps.setString(15, newProgramParameter.getAlternativeValue()
				.toUpperCase());
		ps.setShort(16, newProgramParameter.getOrder().shortValue());
		ps.setLong(17, newProgramParameter.getProgramCode().longValue());
		ps.setLong(18, newProgramParameter.getFixedQueryCode().longValue());
		result = ps.execute();

		if (result) {
			Statement stm = conn.createStatement();
			ResultSet rst = stm
					.executeQuery("SELECT scs_param_repte.currval FROM dual");
			if (rst.next()) {
				newProgramParameter.setCode(new Long(rst.getLong(1)));
			}
			stm.close();
			rst.close();
		}

		ps.close();

		return newProgramParameter;
	}

	/**
	 * Actualiza un registro en la tabla TCS_PARAM_REPTE por la llave primaria.
	 * 
	 * @param ProgramParameterVO
	 *            Value Object con el registro que se va a modificar.
	 * 
	 * @return ProgramParameterVO Registro modificado.
	 * 
	 */
	public ProgramParameterVO updateProgramParameter(
			ProgramParameterVO programParameter) throws SQLException {

		String strSQL = "UPDATE tcs_param_repte " + "SET nombre = ?, "
				+ "descripcion = ?, " + "usuario_crea = ?, "
				+ "terminal_crea = ?, " + "usuario_modifica = ?, "
				+ "terminal_modifica = ?, " + "desde_vigencia = ?, "
				+ "hasta_vigencia = ?, " + "vigencia = ?, " + "tipo = ?, "
				+ "oblig = ?, " + "etiqueta = ?, " + "tipo_dato = ?, "
				+ "val_defecto = ?, " + "val_alterno = ?, " + "orden = ?, "
				+ "prg_codigo = ?, " + "cfj_codigo = ? " + "WHERE codigo = ?";

		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setString(1, programParameter.getName().toUpperCase());
		ps.setString(2, programParameter.getDescription().toUpperCase());
		ps.setString(3, programParameter.getWebUserCrea());
		ps.setString(4, "WEB=" + programParameter.getWebClientCrea());
		ps.setString(5, programParameter.getWebUserModif());
		ps.setString(6, "WEB=" + programParameter.getWebClientModif());
		ps.setDate(7, programParameter.getEffectiveFrom());
		ps.setDate(8, programParameter.getEffectiveUntil());
		ps.setString(9, programParameter.getUse().toUpperCase());
		ps.setString(10, programParameter.getParameterType().toUpperCase());
		ps.setString(11, programParameter.getMandatory().toUpperCase());
		ps.setString(12, programParameter.getLabel().toUpperCase());
		ps.setString(13, programParameter.getDataType().toUpperCase());
		ps.setString(14, programParameter.getDefaultValue().toUpperCase());
		ps.setString(15, programParameter.getAlternativeValue().toUpperCase());
		ps.setShort(16, programParameter.getOrder().shortValue());
		ps.setLong(17, programParameter.getProgramCode().longValue());
		ps.setLong(18, programParameter.getFixedQueryCode().longValue());
		ps.setLong(19, programParameter.getCode().longValue());
		int updates = ps.executeUpdate();

		if (updates == 0) {
			return null;
		}

		ps.close();

		return programParameter;

	}

	/**
	 * Borra un registro de la tabla TCS_PARAM_REPTE por la llave primaria.
	 * 
	 * @param ProgramParameterVO
	 *            Value Object con el registro que se va a borrar.
	 * 
	 * @return boolean Indicador de exito de la operacion de borrado
	 */
	public boolean deleteProgramParameter(ProgramParameterVO programParameter)
			throws SQLException {

		String strSQL = "DELETE tcs_param_repte " + "WHERE codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setLong(1, programParameter.getCode().longValue());
		boolean deletes = ps.execute();
		ps.close();
		return deletes;
	}

}